package com.cqupt.scanning.system.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.scanning.handler.exception.MyException;
import com.cqupt.scanning.system.acl.entity.AclUser;
import com.cqupt.scanning.system.acl.service.AclUserService;
import com.cqupt.scanning.system.admin.entity.Department;
import com.cqupt.scanning.system.admin.entity.DeviceFoot;
import com.cqupt.scanning.system.admin.entity.DeviceThree;
import com.cqupt.scanning.system.admin.entity.Organization;
import com.cqupt.scanning.system.admin.entity.vo.DeviceVO;
import com.cqupt.scanning.system.admin.mapper.DeviceThreeMapper;
import com.cqupt.scanning.system.admin.service.DepartmentService;
import com.cqupt.scanning.system.admin.service.DeviceFootService;
import com.cqupt.scanning.system.admin.service.DeviceThreeService;
import com.cqupt.scanning.system.admin.service.OrganizationService;
import com.cqupt.scanning.system.utils.common.PasswordEncryption;
import com.cqupt.scanning.system.utils.result.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Random;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 宋宝梁
 * @since 2021-07-06
 */
@Service
public class DeviceThreeServiceImpl extends ServiceImpl<DeviceThreeMapper, DeviceThree> implements DeviceThreeService {

    private AclUserService aclUserService;
    private OrganizationService organizationService;
    private DepartmentService departmentService;


    @Autowired
    @Lazy
    public DeviceThreeServiceImpl(AclUserService aclUserService,
                                 OrganizationService organizationService,
                                 DepartmentService departmentService) {
        this.aclUserService = aclUserService;
        this.organizationService = organizationService;
        this.departmentService = departmentService;

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public R insert(DeviceVO deviceVO) {
        try {
            int count = aclUserService.count(new QueryWrapper<AclUser>().eq("username", deviceVO.getUsername().trim()));
            if (count >= 1) return R.error().message("用户名已存在");

            DeviceThree deviceThree = new DeviceThree();

            AclUser aclUser = new AclUser();
            aclUser.setUsername(deviceVO.getUsername().trim());
            aclUser.setPassword(PasswordEncryption.execute(deviceVO.getPassword().trim()));
            aclUser.setNote("0");
            aclUser.setType(deviceVO.getDevName());
            BeanUtils.copyProperties(deviceVO, deviceThree);
            aclUserService.save(aclUser);

            String DevNumCreateTime = new SimpleDateFormat("ddyyMM").format(System.currentTimeMillis());

            Department department =  departmentService.getOne(new QueryWrapper<Department>().eq("id",deviceVO.getDepId()));
            Organization organization = organizationService.getOne(new QueryWrapper<Organization>().eq("org_num",department.getOrgNum()));

            //标识符+用户id+科室id+医院id+0.001重复概率的随机数 1+5+5+4+3=18位
            String devNum = "T"+String.format("%05d", aclUser.getId())+String.format("%05d", deviceVO.getDepId())+String.format("%04d", organization.getId())+String.format("%03d", new Random().nextInt(1000));
            //年月日时间戳+用户id+科室id+医院id+0.001重复概率的随机数 6+5+5+4+3=23位
            String serialCode = DevNumCreateTime+String.format("%05d", aclUser.getId())+String.format("%05d", deviceVO.getDepId())+String.format("%04d", organization.getId())+String.format("%03d", new Random().nextInt(1000));
            int devCount = baseMapper.selectCount(new QueryWrapper<DeviceThree>().eq("dev_num",devNum));
            if (devCount >= 1 ) return R.error().message("设备编号已存在,请联系管理员！");
            int devCount1 = baseMapper.selectCount(new QueryWrapper<DeviceThree>().eq("serial_code",serialCode));
            if (devCount1 >= 1 ) return R.error().message("设备序列号已存在,请联系管理员！");
            deviceThree.setDevNum(devNum);
            deviceThree.setSerialCode(serialCode);
            deviceThree.setUserId(aclUser.getId());
            baseMapper.insert(deviceThree);
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyException(20001, "添加失败，请重新操作");
        }
    }

    @Override
    public R update(DeviceVO deviceVO) {
        DeviceThree deviceThree = new DeviceThree();
        BeanUtils.copyProperties(deviceVO, deviceThree);
        int id = baseMapper.updateById(deviceThree);
        if (id <= 0) return R.error().message("Update failed");
        return R.ok();
    }

    @Override
    public R delById(Integer id) {
        try {
            DeviceThree deviceThree = baseMapper.selectById(id);
            aclUserService.removeUserById(deviceThree.getUserId());
            baseMapper.deleteById(id);
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyException(20001, "删除失败，请重新操作");
        }
    }

    @Override
    public R getAll(Page<DeviceThree> page, String devNum, String devType) {
        QueryWrapper w =new QueryWrapper<DeviceThree>();
        if(!StrUtil.isEmpty(devNum)){
            w.eq("dev_num",devNum);
        }
        if(!StrUtil.isEmpty(devType)){
            w.eq("dev_type",devType);
        }
        IPage<DeviceThree> devPage = baseMapper.selectPage(page,w);
        List<DeviceThree> records = devPage.getRecords();
        for (DeviceThree record : records) {
            Department department = departmentService.getOne(new QueryWrapper<Department>()
                    .select("dep_name", "org_num").eq("id", record.getDepId()));
            Organization organization = organizationService.getOne(new QueryWrapper<Organization>()
                    .select("org_name", "org_address").eq("org_num", department.getOrgNum()));
            record.setDepName(department.getDepName())
                    .setOrgName(organization.getOrgName())
                    .setOrgAdress(organization.getOrgAddress());
        }
        return R.ok().data("devices", devPage);
    }
}
